using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Data;using THSERP.BusinessEntities;using THSERP.BaseProvider;
using THSLib;using THSERP.BaseProvider;

namespace THSERP.Modules.SaleReturn
{
    public class SaleReturnEntities : ERPModuleEntities
    {
        #region Declare Constant
        public readonly static String strARSaleReturnObjectName = "ARSaleReturns";
        public readonly static String strARSaleReturnItemsObjectName = "ARSaleReturnItems";
        #endregion

        #region Declare all entities variables
        private ARSaleReturnsInfo _aRSaleReturnsObject;
        private ARSaleReturnItemsInfo _aRSaleReturnItemsObject;

        public THSItemsEntityList<SaleReturnItemsEntity> lstARSaleReturnItems;
        public THSList<ARInvoiceItemsInfo> lstARReferenceInvoiceItems;
        public THSList<ARDocumentPaymentDetailsInfo> lstARDocumentPaymentDetails;
        #endregion

        #region Public Properties
        public ARSaleReturnsInfo ARSaleReturnsObject
        {
            get
            {
                return _aRSaleReturnsObject;
            }
            set
            {
                _aRSaleReturnsObject = value;
            }
        }
        public ARSaleReturnItemsInfo ARSaleReturnItemsObject
        {
            get
            {
                return _aRSaleReturnItemsObject;
            }
            set
            {
                _aRSaleReturnItemsObject = value;
            }
        }

        public THSItemsEntityList<SaleReturnItemsEntity> ARSaleReturnItemsList
        {
            get
            {
                return lstARSaleReturnItems;
            }
            set
            {
                lstARSaleReturnItems = value;
            }
        }

        public THSList<ARInvoiceItemsInfo> ARReferenceInvoiceItemsList
        {
            get
            {
                return lstARReferenceInvoiceItems;
            }
            set
            {
                lstARReferenceInvoiceItems = value;
            }
        }

        public THSList<ARDocumentPaymentDetailsInfo> ARDocumentPaymentDetailsList
        {
            get
            {
                return lstARDocumentPaymentDetails;
            }
            set
            {
                lstARDocumentPaymentDetails = value;
            }
        }
        #endregion

        #region Constructor
        public SaleReturnEntities()
            : base()
        {
            _aRSaleReturnsObject = new ARSaleReturnsInfo();

            _aRSaleReturnItemsObject = new ARSaleReturnItemsInfo();

            lstARSaleReturnItems = new THSItemsEntityList<SaleReturnItemsEntity>();
            lstARReferenceInvoiceItems = new THSList<ARInvoiceItemsInfo>();
            lstARDocumentPaymentDetails = new THSList<ARDocumentPaymentDetailsInfo>();
        }

        #endregion

        #region Init Main Object,Module Objects functions
        public override void InitMainObject()
        {
            MainObject = ARSaleReturnsObject;
        }

        public override void InitModuleObjects()
        {
            ModuleObjects.Add("ARSaleReturnItems", ARSaleReturnItemsObject);
        }

        public override void InitModuleObjectList()
        {
            lstARSaleReturnItems = new THSItemsEntityList<SaleReturnItemsEntity>();
            lstARSaleReturnItems.InitTHSList(this, 
                THSUtil.GetTableNameFromBusinessObjectType(typeof(ARSaleReturnsInfo)),
                THSUtil.GetTableNameFromBusinessObjectType(typeof(ARSaleReturnItemsInfo)));
            lstARReferenceInvoiceItems.InitTHSList(this, String.Empty, Invoice.InvoiceEntities.strARInvoiceItemsObjectName);
            lstARDocumentPaymentDetails.InitTHSList(this, String.Empty, THSUtil.GetTableNameFromBusinessObjectType(typeof(ARDocumentPaymentDetailsInfo)));
        }

        public override void InitGridControlInTHSList()
        {
            lstARSaleReturnItems.InitTHSListGridControl();
            lstARDocumentPaymentDetails.InitTHSListGridControl();
        }

        public override void SetDefaultModuleObjectsList()
        {
            try
            {
                lstARSaleReturnItems.SetDefaultListAndRefreshGridControl();
                ResetPaymentList();
                lstARReferenceInvoiceItems.SetDefaultListAndRefreshGridControl();
            }
            catch (Exception)
            {
                return;
            }
        }

        #endregion

        #region Invalidate Module Objects Functions
        public override void InvalidateModuleObjects(int iObjectID)
        {
            ARSaleReturnItemsList.Invalidate(iObjectID);
            ICProductAttributesController objProductAttributesController = new ICProductAttributesController();
            foreach (SaleReturnItemsEntity entItem in ARSaleReturnItemsList)
            {
                entItem.ARSaleReturnItemProductAttribute = objProductAttributesController.GetAttributeValueByProductAttributeID(entItem.FK_ICProductAttributeID);
            }
            if (ARSaleReturnItemsList.Count > 0)
                ARSaleReturnItemsList.GridViewFocusRow(0);

            ARSaleReturnsInfo objSaleReturnsInfo = (ARSaleReturnsInfo)MainObject;
            ARInvoicesInfo objInvoicesInfo = new ARInvoicesController().GetInvoiceByReference(objSaleReturnsInfo.ARSaleReturnNo);
            if (((SaleReturnModule)Module).ModuleAction == SaleReturnModule.cstModuleActionNone)
            {
                ResetPaymentList();
                if (objInvoicesInfo != null)
                {
                    AROpenDocumentsInfo objOpenDocumentsInfo = (AROpenDocumentsInfo)new AROpenDocumentsController().GetFirstObjectByForeignColumn("FK_ARInvoiceID", objInvoicesInfo.ARInvoiceID);
                    if (objOpenDocumentsInfo != null)
                    {
                        ARDocumentPaymentsInfo objDocumentPaymentsInfo = (ARDocumentPaymentsInfo)new ARDocumentPaymentsController().GetFirstObjectByForeignColumn("FK_AROpenDocumentID", objOpenDocumentsInfo.AROpenDocumentID);
                        if (objDocumentPaymentsInfo != null)
                        {
                            ARDocumentPaymentDetailsController objDocumentPaymentDetailsController = new ARDocumentPaymentDetailsController();
                            DataSet ds = objDocumentPaymentDetailsController.GetAllDataByForeignColumn("FK_ARDocumentPaymentID", objDocumentPaymentsInfo.ARDocumentPaymentID);
                            if (ds.Tables.Count > 0)
                            {
                                foreach (DataRow row in ds.Tables[0].Rows)
                                {
                                    ARDocumentPaymentDetailsInfo objDocumentPaymentDetailsInfo = (ARDocumentPaymentDetailsInfo)objDocumentPaymentDetailsController.GetObjectFromDataRow(row);
                                    int pos = ARDocumentPaymentDetailsList.PosOf("ARPaymentMethodCombo", objDocumentPaymentDetailsInfo.ARPaymentMethodCombo);
                                    if (pos >= 0)
                                    {
                                        THSUtil.CopyObjectItems(objDocumentPaymentDetailsInfo, ARDocumentPaymentDetailsList[pos], String.Empty);
                                        ARDocumentPaymentDetailsList[pos].ARDocumentPaymentDetailAmount = Math.Abs(ARDocumentPaymentDetailsList[pos].ARDocumentPaymentDetailAmount);
                                    }
                                }
                            }
                        }
                    }
                }
                ARDocumentPaymentDetailsList.GridControl.RefreshDataSource();
            }
        }

        public void ResetPaymentList()
        {
            foreach (ARDocumentPaymentDetailsInfo objDocumentPaymentDetailsInfo in ARDocumentPaymentDetailsList)
            {
                objDocumentPaymentDetailsInfo.ARDocumentPaymentDetailAmount = 0;
                objDocumentPaymentDetailsInfo.ARDocumentPaymentDetailChangeAmount = 0;
                objDocumentPaymentDetailsInfo.ARDocumentPaymentDetailInfo = String.Empty;
                objDocumentPaymentDetailsInfo.FK_ARDocumentPaymentID = 0;
            }
            ARDocumentPaymentDetailsList.GridControl.RefreshDataSource();
        }
        #endregion

        #region Save Module Objects Functions
        public override int SaveMainObject()
        {
            ARSaleReturnItemsList.EndCurrentEdit();
            UpdateTotalAmount();
            return base.SaveMainObject();
        }

        public override void SaveModuleObjects()
        {
            ARSaleReturnItemsList.SaveItemObjects();
        }
        #endregion

        public override void DoActionAfterRemovingItemObject(string strItemTableName)
        {
            UpdateTotalAmount();
        }

        public override void SetValuesAfterValidateProduct(int productAttributeID)
        {
            ICProductAttributesController objProductAttributesController = new ICProductAttributesController();
            ICProductAttributesInfo objProductAttributesInfo = (ICProductAttributesInfo)objProductAttributesController.GetObjectByID(productAttributeID);
            if (objProductAttributesInfo != null)
            {
                ARSaleReturnItemsInfo objSaleReturnItemsInfo = (ARSaleReturnItemsInfo)ModuleObjects[SaleReturnEntities.strARSaleReturnItemsObjectName];
                objSaleReturnItemsInfo.FK_ICProductID = objProductAttributesInfo.FK_ICProductID;
                ARSaleReturnItemsList.SetDefaultValuesFromProduct(objProductAttributesInfo.FK_ICProductID);
                objSaleReturnItemsInfo.FK_ICStockID = (MainObject as ARSaleReturnsInfo).FK_ICStockID;
                objSaleReturnItemsInfo.FK_ICDepartmentID = objProductAttributesInfo.FK_ICDepartmentID;
                objSaleReturnItemsInfo.FK_ICProductGroupID = objProductAttributesInfo.FK_ICProductGroupID;
                objSaleReturnItemsInfo.FK_ICProductAttributeID = objProductAttributesInfo.ICProductAttributeID;
                objSaleReturnItemsInfo.ARSaleReturnItemProductAttribute = objProductAttributesController.GetAttributeValueByProductAttributeID(objProductAttributesInfo.ICProductAttributeID);
                objSaleReturnItemsInfo.ARSaleReturnItemProductSerialNo = objProductAttributesInfo.ICProductAttributeSerialNo;
                UpdateModuleObjectBindingSource(SaleReturnEntities.strARSaleReturnItemsObjectName);
            }
        }

        public void SetDefaultValuesFromCustomer(ARCustomersInfo objCustomersInfo, bool applyCustomerPriceLevel)
        {
            if (applyCustomerPriceLevel)
            {
                //Update price level of sale receipt
                ((ARSaleReturnsInfo)MainObject).FK_ARPriceLevelID = objCustomersInfo.FK_ARPriceLevelID;
                UpdateMainObjectBindingSource();

                //Update all item price basing on price level
                foreach (SaleReturnItemsEntity entItem in ARSaleReturnItemsList)
                    SetProductPrice(entItem, SaleReturnEntities.strARSaleReturnItemsObjectName);
                ARSaleReturnItemsList.GridControl.RefreshDataSource();
                UpdateTotalAmount();
            }
        }

        public void UpdateTotalAmount()
        {
            if (!Module.Toolbar.IsNullOrNoneAction())
            {
                ARSaleReturnsInfo objSaleReturnsInfo = (ARSaleReturnsInfo)MainObject;
                objSaleReturnsInfo.ARSaleReturnNetAmount = 0;
                objSaleReturnsInfo.ARSaleReturnTaxAmount = 0;
                objSaleReturnsInfo.ARSaleReturnSubTotalAmount = 0;
                foreach (SaleReturnItemsEntity entItem in ARSaleReturnItemsList)
                {
                    objSaleReturnsInfo.ARSaleReturnNetAmount += entItem.ARSaleReturnItemNetAmount;
                    objSaleReturnsInfo.ARSaleReturnTaxAmount += entItem.ARSaleReturnItemTaxAmount;
                    objSaleReturnsInfo.ARSaleReturnSubTotalAmount += entItem.ARSaleReturnItemTotalAmount;
                }
                objSaleReturnsInfo.ARSaleReturnDiscountFix = objSaleReturnsInfo.ARSaleReturnSubTotalAmount * objSaleReturnsInfo.ARSaleReturnDiscountPerCent / 100;
                objSaleReturnsInfo.ARSaleReturnTotalAmount = objSaleReturnsInfo.ARSaleReturnSubTotalAmount - objSaleReturnsInfo.ARSaleReturnDiscountFix;
                UpdateMainObjectBindingSource();
            }
        }

        #region Functions for completing transaction
        public override bool CompleteTransaction()
        {
            //Change quantity, amount of sale return and its all items to negative for generation
            ARSaleReturnsController objSaleReturnsController = new ARSaleReturnsController();
            ARSaleReturnsInfo objSaleReturnsInfo = (ARSaleReturnsInfo)MainObject.Clone();
            objSaleReturnsInfo.ARSaleReturnNetAmount = -objSaleReturnsInfo.ARSaleReturnNetAmount;
            objSaleReturnsInfo.ARSaleReturnTaxAmount = -objSaleReturnsInfo.ARSaleReturnTaxAmount;
            objSaleReturnsInfo.ARSaleReturnSubTotalAmount = -objSaleReturnsInfo.ARSaleReturnSubTotalAmount;
            objSaleReturnsInfo.ARSaleReturnDiscountFix = -objSaleReturnsInfo.ARSaleReturnDiscountFix;
            objSaleReturnsInfo.ARSaleReturnTotalAmount = -objSaleReturnsInfo.ARSaleReturnTotalAmount;
            
            foreach (SaleReturnItemsEntity entItem in ARSaleReturnItemsList)
            {
                entItem.ARSaleReturnItemProductQty = -entItem.ARSaleReturnItemProductQty;
                entItem.ARSaleReturnItemPrice = -entItem.ARSaleReturnItemPrice;
                entItem.ARSaleReturnItemNetAmount = -entItem.ARSaleReturnItemNetAmount;
                entItem.ARSaleReturnItemDiscountAmount = -entItem.ARSaleReturnItemDiscountAmount;
                entItem.ARSaleReturnItemTaxAmount = -entItem.ARSaleReturnItemTaxAmount;
                entItem.ARSaleReturnItemTotalAmount = -entItem.ARSaleReturnItemTotalAmount;
            }

            //Generate invoice
            ARInvoicesController objInvoicesController = new ARInvoicesController();
            ARInvoicesInfo objInvoicesInfo = GenerateInvoiceFromSaleReturn(objSaleReturnsInfo);
            objInvoicesInfo.ARInvoiceNo = THSApp.GetMainObjectNo("Invoice");

            int iInvoiceID = objInvoicesController.CreateObject(objInvoicesInfo);
            THSApp.UpdateObjectNumbering("Invoice");
            if (iInvoiceID > 0)
            {
                //Generate all items of invoice
                CreateInvoiceItemsFromSaleReturnItems(iInvoiceID);
            }

            //Generate open document
            AROpenDocumentsController objOpenDocumentsController = new AROpenDocumentsController();
            AROpenDocumentsInfo objOpenDocumentsInfo = GenerateOpenDocumentFromInvoice(objInvoicesInfo);
            objOpenDocumentsController.CreateObject(objOpenDocumentsInfo);
            CustomerPayment.CustomerPaymentModule.TakePayment(objOpenDocumentsInfo, objOpenDocumentsInfo.AROpenDocumentTotalAmount, ARDocumentPaymentDetailsList);

            //Update SaleReturn status
            objSaleReturnsInfo = (ARSaleReturnsInfo)MainObject;
            objSaleReturnsInfo.AAUpdatedDate = DateTime.Now;
            objSaleReturnsInfo.AAUpdatedUser = THSApp.CurrentUser;
            objSaleReturnsInfo.ARSaleReturnStatus = SaleReturnModule.cstSaleReturnStatusComplete;
            objSaleReturnsController.UpdateObject(objSaleReturnsInfo);

            //Update Inventory
            ARSaleReturnItemsList.UpdateInventory(BusinessObject.DefaultAAStatus);
        
            //Rollback to original state for right reflection on screen
            foreach (SaleReturnItemsEntity entItem in ARSaleReturnItemsList)
            {
                entItem.ARSaleReturnItemProductQty = -entItem.ARSaleReturnItemProductQty;
                entItem.ARSaleReturnItemPrice = -entItem.ARSaleReturnItemPrice;
                entItem.ARSaleReturnItemNetAmount = -entItem.ARSaleReturnItemNetAmount;
                entItem.ARSaleReturnItemDiscountAmount = -entItem.ARSaleReturnItemDiscountAmount;
                entItem.ARSaleReturnItemTaxAmount = -entItem.ARSaleReturnItemTaxAmount;
                entItem.ARSaleReturnItemTotalAmount = -entItem.ARSaleReturnItemTotalAmount;
            }

            return true;
        }

        public override bool IsInvalidInventory()
        {
            return ARSaleReturnItemsList.IsInvalidInventory(TransactionUtil.cstInventoryReceipt);
        }

        public override void UpdateInventory(ERPModuleItemsEntity entItems, string strUpdateStatus)
        {
            SaleReturnItemsEntity entSaleReturnItem = (SaleReturnItemsEntity)entItems;
            if (strUpdateStatus == BusinessObject.DefaultAAStatus)
            {
                //Update Inventory Stock
                if (entSaleReturnItem.AAStatus == BusinessObject.DefaultAAStatus)
                {
                    int iICInventoryStockID = TransactionUtil.UpdateInventoryStock(
                                                entSaleReturnItem.FK_ICProductID, entSaleReturnItem.FK_ICProductAttributeID, entSaleReturnItem.FK_ICStockID, entSaleReturnItem.ARSaleReturnItemProductQty,
                                                TransactionUtil.cstInventoryShipment);
                }
            }
            else if (strUpdateStatus == BusinessObject.DeletedAAStatus)
            {
                if (entSaleReturnItem.AAStatus == BusinessObject.DefaultAAStatus)
                {
                    //Update Inventory Stock
                    int iICInventoryStockID = TransactionUtil.UpdateInventoryStock(
                                                    entSaleReturnItem.FK_ICProductID, entSaleReturnItem.FK_ICProductAttributeID, entSaleReturnItem.FK_ICStockID, -entSaleReturnItem.ARSaleReturnItemProductQty,
                                                    TransactionUtil.cstInventoryShipment);
                }
            }
        }

        public ARInvoicesInfo GenerateInvoiceFromSaleReturn(ARSaleReturnsInfo objSaleReturnsInfo)
        {
            ARInvoicesInfo objInvoicesInfo = new ARInvoicesInfo();
            THSUtil.CopyMainObjects(objSaleReturnsInfo, objInvoicesInfo);
            
            //Set own properties of invoice
            objInvoicesInfo.AACreatedUser = THSApp.CurrentUser;
            objInvoicesInfo.AACreatedDate = DateTime.Now;
            objInvoicesInfo.ARInvoiceReference = objSaleReturnsInfo.ARSaleReturnNo;
            objInvoicesInfo.ARInvoiceTypeCombo = ADConfigValueUtility.cstOpenDocumentTypeGoodsRefund;
            objInvoicesInfo.ARInvoiceStatus = Invoice.InvoiceModule.cstInvoiceStatusComplete;
            if (THSApp.CurrentCompanyInfo != null)
                objInvoicesInfo.FK_BRBranchID = THSApp.CurrentCompanyInfo.FK_BRBranchID;
            return objInvoicesInfo;
        }

        public void CreateInvoiceItemsFromSaleReturnItems(int iInvoiceID)
        {
            
            ARInvoiceItemsController objInvoiceItemsController = new ARInvoiceItemsController();

            foreach (SaleReturnItemsEntity item in ARSaleReturnItemsList)
            {
                ARInvoiceItemsInfo objInvoiceItemsInfo = new ARInvoiceItemsInfo();
                ARSaleReturnItemsInfo objSaleReturnItemsInfo = (ARSaleReturnItemsInfo)item.SetToBusinessObject(SaleReturnEntities.strARSaleReturnItemsObjectName);
                THSUtil.CopyObjectItems(objSaleReturnItemsInfo, objInvoiceItemsInfo, Modules.Invoice.InvoiceEntities.strARInvoicesObjectName);
                objInvoiceItemsInfo.FK_ARInvoiceID = iInvoiceID;
                objInvoiceItemsController.CreateObject(objInvoiceItemsInfo);
            }
        }

        public AROpenDocumentsInfo GenerateOpenDocumentFromInvoice(ARInvoicesInfo objInvoicesInfo)
        {
            
            AROpenDocumentsInfo objOpenDocumentsInfo = new AROpenDocumentsInfo();
            THSUtil.CopyMainObjects(objInvoicesInfo, objOpenDocumentsInfo);

            //Set own properties of open document
            objOpenDocumentsInfo.AACreatedUser = THSApp.CurrentUser;
            objOpenDocumentsInfo.AACreatedDate = DateTime.Now;
            objOpenDocumentsInfo.AROpenDocumentNo = objInvoicesInfo.ARInvoiceReference;
            objOpenDocumentsInfo.FK_ARInvoiceID = objInvoicesInfo.ARInvoiceID;
            objOpenDocumentsInfo.AROpenDocumentType = ADConfigValueUtility.cstOpenDocumentTypeGoodsRefund;
            return objOpenDocumentsInfo;
        }
        #endregion
    }
}
